#include <QtGui>

#include "src/color.h"
#include "src/particle.h"
#include "src/fabric.h"
#include "particleDialog.h"
#include "particleTreeItem.h"
#include "fabricTreeItem.h"

ParticleDialog::ParticleDialog(ParticleTreeItem *_item, QWidget *_parent)
    : QDialog(_parent), item(_item){

    particle = item->getParticle();
    unsigned int id = particle->getID();
    setWindowTitle(QString::fromUtf8("Modificando a partícula ").append(QString::number(id)));


    Color color = particle->getActualColor();
    colorR = color.r * 255;
    colorG = color.g * 255;
    colorB = color.b * 255;
    colorAlpha = color.alpha * 255;

    mass = particle->getMass();
    kdAir = particle->getKd();
    miC = particle->getMiC();

    Vector3D position = particle->getPosition();
    positionX = position.x;
    positionY = position.y;
    positionZ = position.z;

    Vector3D velocity = particle->getVelocity();
    velocityX = velocity.x;
    velocityY = velocity.y;
    velocityZ = velocity.z;

    Fabric *fabric = ((FabricTreeItem *)(((QTreeWidgetItem *)item)->parent())->parent())->getFabric();
    fabric->getState().getParticleFixedState(id, &fixedX, &fixedY, &fixedZ);

    createLayout();
}

ParticleDialog::~ParticleDialog(){
}

void ParticleDialog::createLayout(){
    //--------------------------------------Mass
    QDoubleSpinBox *massDoubleSpinBox = new QDoubleSpinBox();
    massDoubleSpinBox->setRange(0.00001, 10.0);
    massDoubleSpinBox->setSingleStep(1.0);
    massDoubleSpinBox->setDecimals(5);
    massDoubleSpinBox->setValue(mass);
    connect(massDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMass(double)));

    QHBoxLayout *massLayout = new QHBoxLayout;
    massLayout->addWidget(massDoubleSpinBox);
    massLayout->addStretch(1);

    QGroupBox *massGroupBox = new QGroupBox(QString::fromUtf8("Massa"));
    massGroupBox->setLayout(massLayout);


    //--------------------------------------Kd de resistencia do ar
    QDoubleSpinBox *kdAirDoubleSpinBox = new QDoubleSpinBox();
    kdAirDoubleSpinBox->setRange(0.0, 10.0);
    kdAirDoubleSpinBox->setSingleStep(0.1);
    kdAirDoubleSpinBox->setDecimals(5);
    kdAirDoubleSpinBox->setValue(kdAir);
    connect(kdAirDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeKdAir(double)));

    QHBoxLayout *kdAirLayout = new QHBoxLayout;
    kdAirLayout->addWidget(kdAirDoubleSpinBox);
    kdAirLayout->addStretch(1);

    QGroupBox *kdAirGroupBox = new QGroupBox(QString::fromUtf8("Kd (resistencia do ar)"));
    kdAirGroupBox->setLayout(kdAirLayout);


    //--------------------------------------MiC
    QDoubleSpinBox *miCDoubleSpinBox = new QDoubleSpinBox();
    miCDoubleSpinBox->setRange(0.0, 10.0);
    miCDoubleSpinBox->setSingleStep(1.0);
    miCDoubleSpinBox->setDecimals(5);
    miCDoubleSpinBox->setValue(miC);
    connect(miCDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeMiC(double)));

    QHBoxLayout *miCLayout = new QHBoxLayout;
    miCLayout->addWidget(miCDoubleSpinBox);
    miCLayout->addStretch(1);

    QGroupBox *miCGroupBox = new QGroupBox(QString::fromUtf8("Atrito"));
    miCGroupBox->setLayout(miCLayout);



    //--------------------------------------Posição
    QLabel *positionXLabel = new QLabel(tr("X:"));

    QDoubleSpinBox *positionXDoubleSpinBox = new QDoubleSpinBox();
    positionXDoubleSpinBox->setRange(-50.0, 50.0);
    positionXDoubleSpinBox->setSingleStep(1.0);
    positionXDoubleSpinBox->setValue(positionX);
    connect(positionXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changePositionX(double)));


    QLabel *positionYLabel = new QLabel(tr("Y:"));

    QDoubleSpinBox *positionYDoubleSpinBox = new QDoubleSpinBox();
    positionYDoubleSpinBox->setRange(-50.0, 50.0);
    positionYDoubleSpinBox->setSingleStep(1.0);
    positionYDoubleSpinBox->setValue(positionY);
    connect(positionYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changePositionY(double)));


    QLabel *positionZLabel = new QLabel(tr("Z:"));

    QDoubleSpinBox *positionZDoubleSpinBox = new QDoubleSpinBox();
    positionZDoubleSpinBox->setRange(-50.0, 50.0);
    positionZDoubleSpinBox->setSingleStep(1.0);
    positionZDoubleSpinBox->setValue(positionZ);
    connect(positionZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changePositionZ(double)));


    QHBoxLayout *positionLayout = new QHBoxLayout;
    positionLayout->addWidget(positionXLabel);
    positionLayout->addWidget(positionXDoubleSpinBox);
    positionLayout->addStretch(1);
    positionLayout->addWidget(positionYLabel);
    positionLayout->addWidget(positionYDoubleSpinBox);
    positionLayout->addStretch(1);
    positionLayout->addWidget(positionZLabel);
    positionLayout->addWidget(positionZDoubleSpinBox);
    positionLayout->addStretch(1);

    QGroupBox *positionGroupBox = new QGroupBox(QString::fromUtf8("Posição"));
    positionGroupBox->setLayout(positionLayout);







    //--------------------------------------Velocidade
    QLabel *velocityXLabel = new QLabel(tr("X:"));

    QDoubleSpinBox *velocityXDoubleSpinBox = new QDoubleSpinBox();
    velocityXDoubleSpinBox->setRange(-50.0, 50.0);
    velocityXDoubleSpinBox->setSingleStep(1.0);
    velocityXDoubleSpinBox->setValue(velocityX);
    connect(velocityXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeVelocityX(double)));


    QLabel *velocityYLabel = new QLabel(tr("Y:"));

    QDoubleSpinBox *velocityYDoubleSpinBox = new QDoubleSpinBox();
    velocityYDoubleSpinBox->setRange(-50.0, 50.0);
    velocityYDoubleSpinBox->setSingleStep(1.0);
    velocityYDoubleSpinBox->setValue(velocityY);
    connect(velocityYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeVelocityY(double)));


    QLabel *velocityZLabel = new QLabel(tr("Z:"));

    QDoubleSpinBox *velocityZDoubleSpinBox = new QDoubleSpinBox();
    velocityZDoubleSpinBox->setRange(-50.0, 50.0);
    velocityZDoubleSpinBox->setSingleStep(1.0);
    velocityZDoubleSpinBox->setValue(velocityZ);
    connect(velocityZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeVelocityZ(double)));


    QHBoxLayout *velocityLayout = new QHBoxLayout;
    velocityLayout->addWidget(velocityXLabel);
    velocityLayout->addWidget(velocityXDoubleSpinBox);
    velocityLayout->addStretch(1);
    velocityLayout->addWidget(velocityYLabel);
    velocityLayout->addWidget(velocityYDoubleSpinBox);
    velocityLayout->addStretch(1);
    velocityLayout->addWidget(velocityZLabel);
    velocityLayout->addWidget(velocityZDoubleSpinBox);
    velocityLayout->addStretch(1);

    QGroupBox *velocityGroupBox = new QGroupBox(QString::fromUtf8("Velocidade"));
    velocityGroupBox->setLayout(velocityLayout);




    //--------------------------------------Fixos
    QCheckBox *fixedXCheckBox = new QCheckBox("X:");
    fixedXCheckBox->setChecked(fixedX);
    connect(fixedXCheckBox, SIGNAL(toggled(bool)), this, SLOT(changeFixedX(bool)));

    QCheckBox *fixedYCheckBox = new QCheckBox("Y:");
    fixedYCheckBox->setChecked(fixedY);
    connect(fixedYCheckBox, SIGNAL(toggled(bool)), this, SLOT(changeFixedY(bool)));

    QCheckBox *fixedZCheckBox = new QCheckBox("Z:");
    fixedZCheckBox->setChecked(fixedZ);
    connect(fixedZCheckBox, SIGNAL(toggled(bool)), this, SLOT(changeFixedZ(bool)));

    QHBoxLayout *fixedLayout = new QHBoxLayout;
    fixedLayout->addWidget(fixedXCheckBox);
    fixedLayout->addStretch(1);
    fixedLayout->addWidget(fixedYCheckBox);
    fixedLayout->addStretch(1);
    fixedLayout->addWidget(fixedZCheckBox);
    fixedLayout->addStretch(1);

    QGroupBox *fixedGroupBox = new QGroupBox(QString::fromUtf8("Fixar em:"));
    fixedGroupBox->setLayout(fixedLayout);



    //--------------------------------------Cor
    colorPushButton = new QPushButton(tr("Cor"));
    connect(colorPushButton, SIGNAL(clicked()), this, SLOT(changeColor()));
    setButtonColor();


    //--------------------------------------Botões
    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(acceptChange()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    buttonBox->setLocale(QLocale(QLocale::Portuguese, QLocale::Brazil));


    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(massGroupBox);
    mainLayout->addWidget(kdAirGroupBox);
    mainLayout->addWidget(miCGroupBox);
    mainLayout->addWidget(positionGroupBox);
    mainLayout->addWidget(velocityGroupBox);
    mainLayout->addWidget(fixedGroupBox);
    mainLayout->addWidget(colorPushButton);
    mainLayout->addWidget(buttonBox);
    mainLayout->addStretch(1);

    setLayout(mainLayout);
}

void ParticleDialog::setButtonColor(){
    //    QString colorStr = QString::fromUtf8("color: rgb(255, 255, 255);\n" "background-color: rgb(85, 0, 0, 255);");
    QString colorStr;
    if(colorR + colorB + colorG + colorAlpha < 600){
        colorStr = QString::fromUtf8("color: rgb(255, 255, 255);\n");
    }else{
        colorStr = QString::fromUtf8("color: rgb(0, 0, 0);\n");
    }
    colorStr.append(QString::fromUtf8("background-color: rgb("));
    colorStr.append(QString::number(colorR));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorG));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorB));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorAlpha));
    colorStr.append(QString::fromUtf8(");"));

    colorPushButton->setStyleSheet(colorStr);
}

void ParticleDialog::acceptChange(){

    ///TODO
    ///fazer os calculos pararem (pause)
    ///voltar um passo de tempo
    ///atualizar a mudança
    ///fazer os calculos voltarem
//    std::cout <<"Antes de emitir" <<std::endl;

    emit startPauseSimulation(false);


    particle->setColor(Color(colorR / 255.0, colorG / 255.0, colorB / 255.0, colorAlpha / 255.0));

    particle->setMass(mass);
    particle->setKd(kdAir);
    particle->setMiC(miC);

    particle->setPosition(Vector3D(positionX, positionY, positionZ));
    particle->setVelocity(Vector3D(velocityX, velocityY, velocityZ));

    Fabric *fabric = ((FabricTreeItem *)(((QTreeWidgetItem *)item)->parent())->parent())->getFabric();
    fabric->setParticleState(particle->getID(), fixedX, fixedY, fixedZ, Vector3D(positionX, positionY, positionZ), Vector3D(velocityX, velocityY, velocityZ));

    emit startPauseSimulation(true);

    emit done();

//    std::cout <<"DONE" <<std::endl;

    accept();
}

void ParticleDialog::changeColor(){
    QColor color = QColorDialog::getColor(QColor(colorR, colorG, colorB, colorAlpha), this, "Escolha a cor", QColorDialog::ShowAlphaChannel);
    if (color.isValid()){
        colorR = color.red();
        colorG = color.green();
        colorB = color.blue();
        colorAlpha = color.alpha();
    }
    setButtonColor();
}

void ParticleDialog::changeMass(double _m){
    mass = _m;
}

void ParticleDialog::changeKdAir(double _kd){
    kdAir = _kd;
}

void ParticleDialog::changeMiC(double _miC){
    miC = _miC;
}

void ParticleDialog::changePositionX(double _x){
    positionX = _x;
}

void ParticleDialog::changePositionY(double _y){
    positionY = _y;
}

void ParticleDialog::changePositionZ(double _z){
    positionZ = _z;
}

void ParticleDialog::changeVelocityX(double _x){
    velocityX = _x;
}

void ParticleDialog::changeVelocityY(double _y){
    velocityY = _y;
}

void ParticleDialog::changeVelocityZ(double _z){
    velocityZ = _z;
}

void ParticleDialog::changeFixedX(bool _x){
    fixedX = _x;
}

void ParticleDialog::changeFixedY(bool _y){
    fixedY = _y;
}

void ParticleDialog::changeFixedZ(bool _z){
    fixedZ = _z;
}
